"""
CSPBuilder plugin

Provides an editor functionality for python code files

Copyright (c) 2008 Rune M. Friborg, runef@diku.dk.
See LICENSE.txt for licensing details (GPLv2).
"""

PLUGIN_NAME = "CodeEditor"

try:
    import cPickle as pickle
except:
    import pickle

import sys
import os
import wx

from extensions import cspxml
from plugins.builder import *


class PluginCodeEditor(PluginBUILDER):

    def __init__(self, pluginManager):
        PluginBUILDER.__init__(self, pluginManager, PLUGIN_NAME)

        self.home = os.getenv('USERPROFILE') or os.getenv('HOME')
        self.confPathAndFilename = self.home + '/.cspbuilder/builder.conf'

        if sys.platform == 'darwin':
            self.cmd_default = 'open -a TextEdit %f'
        elif sys.platform == 'linux2':
            self.cmd_default = 'emacs %f'
        elif sys.platform == 'win32':
            self.cmd_default = 'notepad.exe %f'


        self.cmd = self.cmd_default
        self._load_pref()

        self.pluginman = pluginManager

    def _prefmenu_activate(self, frame, event):
        
        dialog = wx.Dialog(frame, -1, "Configure editor", style = wx.DEFAULT_FRAME_STYLE | wx.WANTS_CHARS )

        win = wx.Panel(dialog, -1)

        panelSizer = wx.BoxSizer(wx.HORIZONTAL)

        t = wx.TextCtrl(win, -1, self.cmd, size=(300, -1))
        panelSizer.Add(t, 0, wx.ALL, 5)

        btnOK = wx.Button(win, wx.ID_OK, " Ok ")

        panelSizer.Add(btnOK, 0, wx.ALL | wx.ALIGN_RIGHT, 5)

        win.SetSizer(panelSizer)
        win.SetAutoLayout(True)

        dialog.SetClientSize(wx.Size(400,60))

        if (dialog.ShowModal() == wx.ID_OK):
            self.cmd = t.GetValue()

        dialog.Destroy()

        self._save_pref()


    def _prefmenu(self, frame, menu, menuid):
        menu.Append(menuid, 'Configure Editor')
        frame.Bind(wx.EVT_MENU, lambda event:self._prefmenu_activate(frame,event), id=menuid)


    def __load_all_pref(self):

        D = {}
        if os.path.exists(self.confPathAndFilename):
            # Load
            f = open(self.confPathAndFilename, 'r')
            filedata = ''
            for line in f.readlines():
                filedata += line
            D = pickle.loads(filedata)
            f.close()
        return D

    def _save_pref(self):
        
        D = self.__load_all_pref()

        D['codeeditor'] = self.cmd

        f = open(self.confPathAndFilename, "wb")
        f.write(pickle.dumps(D))
        f.close()
        
    def _load_pref(self):

        D = self.__load_all_pref()

        if (D.has_key('codeeditor')):
            self.cmd = D['codeeditor']
        else:
            self.cmd = self.cmd_default

    def _open_editor(self, filename):
        cmd = self.cmd.replace('%f', filename)
        if cmd == self.cmd:
            cmd = self.cmd + ' ' + filename

        os.popen(cmd)

    def _rcmenu(self, frame, menu, obj, menuid):
        menu.Append(menuid, 'Edit Python Code')
        frame.Bind(wx.EVT_MENU, lambda event:self._rcmenu_activate(frame,event), id=menuid)

    def _rcmenu_activate(self, frame, event):
        obj = frame.selection[0]
        self._dcmenu(frame, obj)

    def _dcmenu(self, frame, obj):

        self._load_pref()

        if (obj.cspData.has_key('xml')):

            pyFilesToEdit = []

            # Parse xml and extract code items
            dom = cspxml.parseString(obj.cspData['xml'])

            for code in dom.getElementsByTagName("code"):
                att = cspxml.getAttrList(code)
                if not att['src'] in pyFilesToEdit:
                    pyFilesToEdit.append(att['src'])
                
            dom.unlink()

            for pyFile in pyFilesToEdit:

                # Find file
                pyFileReal = ''
                for path in self.pluginman.getList(pathlist_COMPONENTS):
                    pathAndFilename = path + '/' + pyFile + '.py'
                    if os.path.exists(pathAndFilename):
                        pyFileReal = pathAndFilename
                        break

                if pyFileReal != '':
                    self._open_editor(pyFileReal)
    

def load(pluginManager):

    p = PluginCodeEditor(pluginManager)

    p.addPrefMenuElement(p._prefmenu)
    p.addRightClickElement(location_PROCESS_CODE, p._rcmenu)
    p.addDoubleClickElement(location_PROCESS_CODE, p._dcmenu)

    pluginManager.addPlugin(p)
